package com.ruoyi.web.controller.system;


import com.ruoyi.system.domain.ParkingRate;
import com.ruoyi.system.domain.TmcActivityUser;
import com.ruoyi.system.domain.TmcHouseBill;
import com.ruoyi.system.mapper.TmcCommunityActivityMapper;
import com.ruoyi.system.service.IParkingRateService;
import com.ruoyi.system.service.ITmcActivityUserService;
import com.ruoyi.system.service.ITmcCommunityActivityService;
import com.ruoyi.system.service.PayService;
import com.ruoyi.system.service.impl.TmcHouseInfoServiceImpl;
import com.ruoyi.web.core.HttpCilentPost;
import com.ruoyi.web.core.sdk.WXPayUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import javax.net.ssl.SSLContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Logger;

//小程序支付
@RestController
@RequestMapping("/system/pay")
public class PayController {
    @Autowired
    private PayService payService;
    @Autowired
    private TmcHouseInfoServiceImpl tmcHouseInfoService;
    @Autowired
    private ITmcCommunityActivityService tmcCommunityActivityService;

    @Autowired
    private ITmcActivityUserService tmcActivityUserService;
    @Autowired
    private IParkingRateService iParkingRateService;

    private int socketTimeout = 10000;// 连接超时时间，默认10秒
    private int connectTimeout = 30000;// 传输超时时间，默认30秒
    private static RequestConfig requestConfig;// 请求器的配置
    private static CloseableHttpClient httpClient;// HTTP请求器


    @GetMapping("/paying")
    public Map<String, Object> payWx(Long id, HttpServletRequest request) {

        TmcHouseBill tmcHouseBill = tmcHouseInfoService.selectTmcHouseBillById(id);
        //通过账单Id找UserId
        Long publicuserId = tmcHouseBill.getPublicuserId();
        System.out.println(publicuserId + "用户id是");
        //通过账单找多少钱
        Double Fee = tmcHouseBill.getTotalFee();
        Map<String, Object> mapRe = new HashMap<String, Object>();
        //获得ip地址
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.indexOf(",") != -1) {
            String[] ips = ip.split(",");
            ip = ips[0].trim();
        }
        try {
            System.out.println("id= " + id);
            Map<String, String> paraMap = new HashMap<String, String>();
            //小程序ID
            paraMap.put("appid", "wxfb26ddee7d388eee");
            //商户号
            paraMap.put("mch_id", "1589342741");
            //随机字符串
            String s = WXPayUtil.generateNonceStr();
            paraMap.put("nonce_str", s);
            System.out.println("第一次签名随机字符串是" + s);
            //商品描述
            paraMap.put("body", "天目智慧社区-水电费");
            //商户订单号
            long l = System.currentTimeMillis();
            String num = l + "";
            paraMap.put("out_trade_no", num);
            //账单表中插入账单号
            HashMap<String, Object> out_trade_no = new HashMap<>();
            out_trade_no.put("id", id);
            out_trade_no.put("out_trade_no", num);
            payService.insertNum(out_trade_no);
            //商户订单号
            System.out.println("商户订单号是" + num);
            //商品价格
            paraMap.put("total_fee", Fee + "");
            //终端ip
            paraMap.put("spbill_create_ip", ip);
            System.out.println("ip是" + ip);
            //通知地址
            paraMap.put("notify_url", "https://zhsq.greatforest.com.cn/system/pay/callback");
            paraMap.put("trade_type", "JSAPI");
            //根据用户id查openid
            String openid = payService.selectOpenId(publicuserId);
            System.out.println("openId是" + openid);
            paraMap.put("openid", openid);


            String sign = WXPayUtil.generateSignature(paraMap, "342623199707207557wangshuliang66");

            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);
            paraMap.put("sign", sign);
            String xmlStr = HttpCilentPost.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
            System.out.println("第一次签名参数XML格式是：" + xml);
            //返给前端预支付id
            String prepay_id = "";
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = map.get("prepay_id").toString();
                System.out.println("预支付Id是：" + prepay_id);

            }
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appId", "wxfb26ddee7d388eee");
            payMap.put("timeStamp", "1618818370412");
            payMap.put("nonceStr", s);
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = WXPayUtil.generateSignature(payMap, "342623199707207557wangshuliang66");
            payMap.put("paySign", paySign);
            mapRe.put("success", true);
            mapRe.put("payMap", payMap);
            System.out.println(payMap);
        } catch (Exception e) {
            mapRe.put("success", false);
            mapRe.put("message", "统一订单接口错误");
            e.printStackTrace();
        }
        return mapRe;

    }

    @GetMapping("/actPaying")
    public Map<String, Object> actPlay(@Param("id") Long id, @Param("publicUserID")Long publicUserID, HttpServletRequest request) {
        //拿到用户报名id去查报名信息
        TmcActivityUser activityUser = tmcCommunityActivityService.selectActivityUser(id);
        System.out.println(activityUser);
        //获得活动Id去查费用
        Long activityId = activityUser.getActivityId();

        int fee = tmcCommunityActivityService.selectFeeById(activityId);
        System.out.println(fee);

        Map<String, Object> mapRe = new HashMap<String, Object>();
        //获得ip地址
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.indexOf(",") != -1) {
            String[] ips = ip.split(",");
            ip = ips[0].trim();
        }
        try {

            System.out.println("id= " + id);
            Map<String, String> paraMap = new HashMap<String, String>();
            //小程序ID
            paraMap.put("appid", "wxfb26ddee7d388eee");
            //商户号
            paraMap.put("mch_id", "1589342741");
            //随机字符串
            String s = WXPayUtil.generateNonceStr();
            paraMap.put("nonce_str", s);
            System.out.println("第一次签名随机字符串是" + s);
            //商品描述
            paraMap.put("body", "天目智慧社区-活动费");
            //商户订单号
            long l = System.currentTimeMillis();
            String num = l + "";
            paraMap.put("out_trade_no", num);
            //参与人表中插入账单号
            activityUser.setOutTradeNo(num);
            tmcActivityUserService.updateTmcActivityUser(activityUser);
            //商户订单号
            System.out.println("商户订单号是" + num);
            //商品价格
            paraMap.put("total_fee", fee + "");
            //终端ip
            paraMap.put("spbill_create_ip", ip);
            System.out.println("ip是" + ip);
            //通知地址
            paraMap.put("notify_url", "https://zhsq.greatforest.com.cn/system/pay/callback2");
            paraMap.put("trade_type", "JSAPI");
            //根据用户id查openid
            String openid = payService.selectOpenId(publicUserID);
            System.out.println("openId是" + openid);
            paraMap.put("openid", openid);


            String sign = WXPayUtil.generateSignature(paraMap, "342623199707207557wangshuliang66");

            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);
            paraMap.put("sign", sign);
            String xmlStr = HttpCilentPost.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);

            System.out.println("第一次签名参数XML格式是：" + xml);
            //返给前端预支付id
            String prepay_id = "";
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = map.get("prepay_id").toString();
                System.out.println("预支付Id是：" + prepay_id);

            }
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appId", "wxfb26ddee7d388eee");
            payMap.put("timeStamp", "1618818370412");
            payMap.put("nonceStr", s);
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = WXPayUtil.generateSignature(payMap, "342623199707207557wangshuliang66");
            payMap.put("paySign", paySign);
            mapRe.put("success", true);
            mapRe.put("payMap", payMap);
            System.out.println(payMap);

        } catch (Exception e) {
            mapRe.put("success", false);
            mapRe.put("message", "统一订单接口错误");
            e.printStackTrace();
        }
        return mapRe;

    }


    @GetMapping("/reMoney")
    public Map<String, String> reMoney(Long id, Long userId) throws Exception {
        System.out.println(id);
        System.out.println(userId);
        TmcActivityUser tmcActivityUser = payService.selectUser(id, userId);
        System.out.println("或得到的user是"+tmcActivityUser);
        //获得用户订单
        String outTradeNo = tmcActivityUser.getOutTradeNo();
        //获得订单费用
        int fee = tmcCommunityActivityService.selectFeeById(id);
        //修改用户状态值
        tmcActivityUser.setState(2L);
        tmcActivityUserService.updateTmcActivityUser(tmcActivityUser);
        Map<String, String> paraMap = new HashMap<String, String>();
        //小程序id
        paraMap.put("appid", "wxfb26ddee7d388eee");
        //商户号
        paraMap.put("mch_id", "1589342741");
        //随机字符串
        paraMap.put("nonce_str", WXPayUtil.generateNonceStr());
        //商户订单号（这里应该是查询出来的）
        paraMap.put("out_trade_no", outTradeNo);
        //订单金额（这里应该也是查询出来的）
        paraMap.put("total_fee", fee + "");
        //退款单号
        paraMap.put("out_refund_no", System.currentTimeMillis()+ "");

        //退款金额()
        paraMap.put("refund_fee", fee + "");
        String sign = WXPayUtil.generateSignature(paraMap, "342623199707207557wangshuliang66");

        paraMap.put("sign", sign);
        String xml = WXPayUtil.mapToXml(paraMap);

        String xmlStr = postData("https://api.mch.weixin.qq.com/secapi/pay/refund", xml); //支付结果通知的xml格式数据
//        String xmlStr = HttpCilentPost.doPost("https://api.mch.weixin.qq.com/secapi/pay/refund", xml);
        Map<String, String> resultMap = WXPayUtil.xmlToMap(xmlStr);
        System.out.println(resultMap);
        return resultMap;
    }


    /**
     * 加载证书
     */
    private static void initCert() throws Exception {
        // 证书密码，默认为商户ID
        String key = "1589342741";
        // 商户证书的路径
        String path = "/home/ruoyi/uploadPath/license/apiclient_cert.p12";

        // 指定读取证书格式为PKCS12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        // 读取本机存放的PKCS12证书文件
        FileInputStream instream = new FileInputStream(new File(path));
        try {
            // 指定PKCS12的密码(商户ID)
            keyStore.load(instream, key.toCharArray());
        } finally {
            instream.close();
        }

        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();

        // 指定TLS版本
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        // 设置httpclient的SSLSocketFactory
        httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }


    /**
     * 通过Https往API post xml数据
     *
     * @param url    API地址
     * @param xmlObj 要提交的XML数据对象
     * @return
     */
    public String postData(String url, String xmlObj) {
        // 加载证书
        try {
            initCert();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String result = null;
        HttpPost httpPost = new HttpPost(url);
        // 得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
        // 根据默认超时限制初始化requestConfig
        requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout)
                .build();
        // 设置请求器的配置
        httpPost.setConfig(requestConfig);
        try {
            HttpResponse response = null;
            try {
                response = httpClient.execute(httpPost);
            } catch (IOException e) {
                e.printStackTrace();
            }
            HttpEntity entity = response.getEntity();
            try {
                result = EntityUtils.toString(entity, "UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } finally {
            httpPost.abort();
        }
        return result;
    }


    @GetMapping("/checkreMoney")
    public String CheckReMoney(Long userId) throws Exception {
        List<TmcActivityUser> list=payService.selectUsers(userId);
        for (int i = 0; i < list.size(); i++) {
            TmcActivityUser tmcActivityUser = list.get(i);
            //获取订单号
            String outTradeNo =tmcActivityUser.getOutTradeNo();

            Map<String, String> paraMap = new HashMap<String, String>();
            //小程序id
            paraMap.put("appid", "wxfb26ddee7d388eee");
            //商户号
            paraMap.put("mch_id", "1589342741");
            //随机字符串
            paraMap.put("nonce_str", WXPayUtil.generateNonceStr());

            //商户订单号
            paraMap.put("out_trade_no", outTradeNo);

            String sign = WXPayUtil.generateSignature(paraMap, "342623199707207557wangshuliang66");

            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);

            String xmlStr = HttpCilentPost.doPost("https://api.mch.weixin.qq.com/pay/refundquery", xml);
            Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
            System.out.println(map);
            if ("SUCCESS".equals(map.get("return_code"))){
               if (null!=map.get("refund_status_0")){
                   //证明修改完成修改状态
                   tmcActivityUser.setState(4L);
                   tmcActivityUserService.updateTmcActivityUser(tmcActivityUser);
               }
               if (null!=map.get("refund_status_1")){
                   //证明修改完成修改状态
                   tmcActivityUser.setState(3L);
                   tmcActivityUserService.updateTmcActivityUser(tmcActivityUser);
                }
               if (null!=map.get("refund_status_2")){
                    //证明修改完成修改状态
                    tmcActivityUser.setState(3L);
                    tmcActivityUserService.updateTmcActivityUser(tmcActivityUser);
                }
            }

        }
        return "吴松霖好帅";


    }

    //回调函数(物业费的回调函数)
    @PostMapping("/callback")
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        Map map = WXPayUtil.xmlToMap(notityXml);
        System.out.println("----------------------------" + map);
        //{transaction_id=4200000999202104202201812627, nonce_str=fZC7Zs9JdM7DBFHY9kMx2OVBezfDaMy2, bank_type=OTHERS, openid=o4ikG5iLC0ARXIyC2yA1CW4BSKug, sign=004B2A878BCC100C6E79C9681C73E40E, fee_type=CNY, mch_id=1589342741, cash_fee=1, out_trade_no=1618904702746, appid=wxfb26ddee7d388eee, total_fee=1, trade_type=JSAPI, result_code=SUCCESS, time_end=20210420154506, is_subscribe=N, return_code=SUCCESS}

        String returnCode = (String) map.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            //如果成功去数据库中修改参数值
            tmcHouseInfoService.updateUserHouseBillInfo(map.get("out_trade_no").toString());
////            //验证签名是否正确
////            Map<String, String> validParams = WXPayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
////            String validStr = PayUtil.createLinkString(validParams);//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
////            String sign = PayUtil.sign(validStr, Configure.getKey(), "utf-8").toUpperCase();//拼装生成服务器端验证的签名
//            // 因为微信回调会有八次之多,所以当第一次回调成功了,那么我们就不再执行逻辑了
//
//            //根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
//            if(sign.equals(map.get("sign"))){
//                /**此处添加自己的业务逻辑代码start**/
//                // bla bla bla....
//                /**此处添加自己的业务逻辑代码end**/
//                //通知微信服务器已经支付成功
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//            } else {
//                System.out.println("微信支付回调失败!签名不一致");
//            }
        } else {
//            我要去清空订单号
            tmcHouseInfoService.updateNum(map.get("out_trade_no").toString());
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    //回调函数(活动费的回调函数)
    @PostMapping("/callback2")
    public void wxNotifyS(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        Map map = WXPayUtil.xmlToMap(notityXml);
        System.out.println("----------------------------" + map);
        //{transaction_id=4200000999202104202201812627, nonce_str=fZC7Zs9JdM7DBFHY9kMx2OVBezfDaMy2, bank_type=OTHERS, openid=o4ikG5iLC0ARXIyC2yA1CW4BSKug, sign=004B2A878BCC100C6E79C9681C73E40E, fee_type=CNY, mch_id=1589342741, cash_fee=1, out_trade_no=1618904702746, appid=wxfb26ddee7d388eee, total_fee=1, trade_type=JSAPI, result_code=SUCCESS, time_end=20210420154506, is_subscribe=N, return_code=SUCCESS}

        String returnCode = (String) map.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            //如果成功去数据库中修改参数值
            payService.updateState(map.get("out_trade_no").toString());
            //恭喜成功报名
//            tmcHouseInfoService.updateUserHouseBillInfo(map.get("out_trade_no").toString());
////            //验证签名是否正确
////            Map<String, String> validParams = WXPayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
////            String validStr = PayUtil.createLinkString(validParams);//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
////            String sign = PayUtil.sign(validStr, Configure.getKey(), "utf-8").toUpperCase();//拼装生成服务器端验证的签名
//            // 因为微信回调会有八次之多,所以当第一次回调成功了,那么我们就不再执行逻辑了
//
//            //根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
//            if(sign.equals(map.get("sign"))){
//                /**此处添加自己的业务逻辑代码start**/
//                // bla bla bla....
//                /**此处添加自己的业务逻辑代码end**/
//                //通知微信服务器已经支付成功
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//            } else {
//                System.out.println("微信支付回调失败!签名不一致");
//            }
        } else {
//          //失败删除一整行

            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }



//
    @GetMapping("/ParkingRate")
    public Map<String, Object> CarpayWx(Long oId,Long publicuserId, HttpServletRequest request) {
        System.out.println(publicuserId + "用户id是");
        //通过账单找多少钱
//        获取账单
        ParkingRate parkingRate = iParkingRateService.selectParkingRateById(oId);
        Double Fee = parkingRate.getPrMoney();
        Map<String, Object> mapRe = new HashMap<String, Object>();
        //获得ip地址
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.indexOf(",") != -1) {
            String[] ips = ip.split(",");
            ip = ips[0].trim();
        }
        try {
            System.out.println("id= " + oId);
            Map<String, String> paraMap = new HashMap<String, String>();
            //小程序ID
            paraMap.put("appid", "wxfb26ddee7d388eee");
            //商户号
            paraMap.put("mch_id", "1589342741");
            //随机字符串
            String s = WXPayUtil.generateNonceStr();
            paraMap.put("nonce_str", s);
            System.out.println("第一次签名随机字符串是" + s);
            //商品描述
            paraMap.put("body", "天目智慧社区-停车费");
            //商户订单号
            long l = System.currentTimeMillis();
            String num = l + "";
            paraMap.put("out_trade_no", num);
            //账单表中插入账单号
            HashMap<String, Object> out_trade_no = new HashMap<>();
            out_trade_no.put("id", oId);
            out_trade_no.put("out_trade_no", num);
            payService.insertNum(out_trade_no);
            //商户订单号
            System.out.println("商户订单号是" + num);
            //商品价格
            paraMap.put("total_fee", Fee + "");
            //终端ip
            paraMap.put("spbill_create_ip", ip);
            System.out.println("ip是" + ip);
            //通知地址
            paraMap.put("notify_url", "https://zhsq.greatforest.com.cn/system/pay/callback");
            paraMap.put("trade_type", "JSAPI");
            //根据用户id查openid
            String openid = payService.selectOpenId(publicuserId);
            System.out.println("openId是" + openid);
            paraMap.put("openid", openid);


            String sign = WXPayUtil.generateSignature(paraMap, "342623199707207557wangshuliang66");

            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);
            paraMap.put("sign", sign);
            String xmlStr = HttpCilentPost.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
            System.out.println("第一次签名参数XML格式是：" + xml);
            //返给前端预支付id
            String prepay_id = "";
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = map.get("prepay_id").toString();
                System.out.println("预支付Id是：" + prepay_id);

            }
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appId", "wxfb26ddee7d388eee");
            payMap.put("timeStamp", "1618818370412");
            payMap.put("nonceStr", s);
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = WXPayUtil.generateSignature(payMap, "342623199707207557wangshuliang66");
            payMap.put("paySign", paySign);
            mapRe.put("success", true);
            mapRe.put("payMap", payMap);
            System.out.println(payMap);
        } catch (Exception e) {
            mapRe.put("success", false);
            mapRe.put("message", "统一订单接口错误");
            e.printStackTrace();
        }
        return mapRe;

    }
    //回调函数(活动费的回调函数)
    @PostMapping("/car/callback")
    public void CarwxNotifyS(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        Map map = WXPayUtil.xmlToMap(notityXml);
        System.out.println("----------------------------" + map);
        //{transaction_id=4200000999202104202201812627, nonce_str=fZC7Zs9JdM7DBFHY9kMx2OVBezfDaMy2, bank_type=OTHERS, openid=o4ikG5iLC0ARXIyC2yA1CW4BSKug, sign=004B2A878BCC100C6E79C9681C73E40E, fee_type=CNY, mch_id=1589342741, cash_fee=1, out_trade_no=1618904702746, appid=wxfb26ddee7d388eee, total_fee=1, trade_type=JSAPI, result_code=SUCCESS, time_end=20210420154506, is_subscribe=N, return_code=SUCCESS}

        String returnCode = (String) map.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            //如果成功去数据库中修改参数值
            payService.updateState(map.get("out_trade_no").toString());
            //恭喜成功报名
//            tmcHouseInfoService.updateUserHouseBillInfo(map.get("out_trade_no").toString());
////            //验证签名是否正确
////            Map<String, String> validParams = WXPayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
////            String validStr = PayUtil.createLinkString(validParams);//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
////            String sign = PayUtil.sign(validStr, Configure.getKey(), "utf-8").toUpperCase();//拼装生成服务器端验证的签名
//            // 因为微信回调会有八次之多,所以当第一次回调成功了,那么我们就不再执行逻辑了
//
//            //根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
//            if(sign.equals(map.get("sign"))){
//                /**此处添加自己的业务逻辑代码start**/
//                // bla bla bla....
//                /**此处添加自己的业务逻辑代码end**/
//                //通知微信服务器已经支付成功
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
//            } else {
//                System.out.println("微信支付回调失败!签名不一致");
//            }
        } else {
//          //失败删除一整行

            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

}